Этот блокнот является частью Bite Size Bayes, введения в вероятность и байесовскую статистику с использованием Python.
Copyright 2020 Allen B. Downey
License: Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
Следующая ячейка загружает файл utils.py
, содержащий некоторую полезную функцию, которая нам понадобится:
from os.path import basename, exists
def download(url):
filename = basename(url)
if not exists(filename):
from urllib.request import urlretrieve
local, _ = urlretrieve(url, filename)
print('Downloaded ' + local)
download('https://github.com/AllenDowney/BiteSizeBayes/raw/master/utils.py')
Downloaded utils.py
Следующая ячейка загружает файл данных, который мы будем использовать в этом блокноте.
download('https://github.com/AllenDowney/BiteSizeBayes/raw/master/gss_bayes.csv')
Downloaded gss_bayes.csv
Если все установлено, то следующая ячейка должна работать без сообщений об ошибках:
import pandas as pd
import numpy as np
from utils import values
В этом блокноте используется вычислительный подход к пониманию вероятности. Мы будем использовать данные Общего социального опроса (General Social Survey), чтобы вычислить вероятность таких предположений, как:
Если я выберу случайного респондента в опросе, какова вероятность, что это будут женщины?
Если я выберу случайного респондента, какова вероятность того, что он будет работать в банковской сфере?
Оттуда мы исследуем две взаимосвязанные концепции:
Конъюнкция, которая представляет собой совместную вероятность того, что оба утверждения верны; например, какова вероятность выбора женщины-банкира?
Условная вероятность, которая представляет собой вероятность того, что одно утверждение верно, при условии, что верно другое; например, учитывая, что респондент - женщина, какова вероятность того, что она банкир?
Я выбрал эти примеры, потому что они связаны с известным экспериментом Тверски и Канемана, которые задали следующий вопрос:
Линде 31 год, она незамужняя, искренняя и очень умная. По специальности философ. Будучи студенткой, она глубоко интересовалась проблемами дискриминации и социальной справедливости, а также участвовала в антиядерных демонстрациях. Что более вероятно?
- Линда - кассир в банке.
- Линда - кассир в банке и активный участник феминистского движения.
Многие люди выбирают второй ответ, предположительно потому, что он кажется более соответствующим описанию. Кажется маловероятным, что Линда будет просто кассиром в банке; если она кассир в банке, вполне вероятно, что она также будет феминисткой.
Но второй ответ не может быть "более вероятным", как задается вопрос. Предположим, мы найдем 1000 человек, которые подходят под описание Линды, и 10 из них работают кассирами в банке.
Сколько из них тоже феминистки? Максимум, их 10; в этом случае оба варианта равновероятны.
Скорее всего, только некоторые из них феминистки; в этом случае второй вариант менее вероятен. Но не может быть больше 10 из 10, поэтому второй вариант не может быть более вероятным.
Ошибка, которую совершают люди, выбирая второй вариант, называется ошибкой конъюнкции или когнитивным искажением.
Это называется заблуждением, потому что это логическая ошибка, и "конъюнкция", потому что "кассир в банке И феминистка" - это логическая конъюнкция.
Если этот пример вызывает у вас дискомфорт, значит, вы в хорошей компании. Биолог Стивен Дж. Гулд писал:
Мне особенно нравится этот пример, потому что я знаю, что [второе] утверждение наименее вероятно, но маленький гомункул в моей голове продолжает прыгать вверх и вниз, крича на меня, "но она не может быть просто кассиром в банке; прочитайте описание."
Если человечек в вашей голове все еще недоволен, возможно, вам поможет этот блокнот.
Здесь я должен определить вероятность, но это оказывается на удивление трудным. Чтобы не увязнуть, прежде чем мы начнем, я начну с простого определения: вероятность - это доля (fraction) набора данных.
Например, если мы опрашиваем 1000 человек, и 20 из них являются кассирами в банке, доля работающих кассирами в банке составляет 0,02 или 2\%. Если мы выберем человека из этой группы случайным образом, вероятность того, что он будет кассиром в банке, составит 2\%.
Под "случайным образом" я подразумеваю, что каждый человек в наборе данных имеет одинаковые шансы быть выбранным, а под "они" я подразумеваю единственное, гендерно-нейтральное местоимение, которое является правильной и полезной особенностью английского языка.
Имея это определение и соответствующий набор данных, мы можем вычислять вероятности путем подсчета.
Для демонстрации я буду использовать набор данных из Общего социального опроса или General Social Survey (GSS).
Следующая ячейка читает данные.
gss = pd.read_csv('gss_bayes.csv', index_col=0)
Результатом является фрейм данных pandas с одной строкой для каждого опрошенного человека и одним столбцом для каждой выбранной мной переменной.
Вот количество строк и столбцов:
gss.shape
(49290, 6)
А вот и первые несколько строк:
gss.head()
year | age | sex | polviews | partyid | indus10 | |
---|---|---|---|---|---|---|
caseid | ||||||
1 | 1974 | 21.0 | 1 | 4.0 | 2.0 | 4970.0 |
2 | 1974 | 41.0 | 1 | 5.0 | 0.0 | 9160.0 |
5 | 1974 | 58.0 | 2 | 6.0 | 1.0 | 2670.0 |
6 | 1974 | 30.0 | 1 | 5.0 | 4.0 | 6870.0 |
7 | 1974 | 48.0 | 1 | 5.0 | 4.0 | 7860.0 |
Столбцы:
caseid
: идентификатор респондента (который является индексом таблицы),
year
: год, когда респондент был опрошен,
age
: возраст респондента на момент опроса,
sex
: мужской или женский,
polviews
: диапазон политических взглядов от либеральных до консервативных,
partyid
: принадлежность к политической партии, демократическая, независимая или республиканская,
indus10
: код отрасли, в которой работает респондент.
Давайте рассмотрим эти переменные более подробно, начиная с indus10
.
Код для "Банковской и связанной с ней деятельности" - 6870, поэтому мы можем выбрать таких банкиров:
banker = (gss['indus10'] == 6870)
Результатом является логическая серия, которая представляет собой серию pandas, содержащую значения True
и False
.
Вот несколько первых записей:
banker.head()
caseid 1 False 2 False 5 False 6 True 7 False Name: indus10, dtype: bool
Мы можем использовать values
, чтобы узнать, сколько раз появляется каждое значение.
values(banker)
counts | |
---|---|
values | |
False | 48562 |
True | 728 |
В этом наборе данных 728 банкиров.
Если мы используем функцию sum
в этой серии, она обрабатывает True
как 1, а False
как 0, поэтому общее количество - это количество банкиров.
banker.sum()
728
Чтобы вычислить долю банкиров, мы можем разделить на количество людей в наборе данных:
banker.sum() / banker.size
0.014769730168391155
Но мы также можем использовать функцию mean
, которая вычисляет долю значений True
в серии:
banker.mean()
0.014769730168391155
Около 1,5% респондентов работают в банковской сфере. Это означает, что если мы выберем случайного человека из набора данных, вероятность того, что он банкир, составляет около 1,5%.
Задание: Значения sex
в столбце кодируются следующим образом:
1 Male
2 Female
Следующая ячейка создает логическую серию, которая имеет значение True
для респондентов-женщин и False
в противном случае.
female = (gss['sex'] == 2)
Используйте values
для отображения количества True
и False
значений у female
.
Используйте sum
, чтобы подсчитать количество респондентов-женщин.
Используйте mean
, чтобы вычислить долю респондентов-женщин.
# Решение здесь
# Решение здесь
# Решение здесь
Доля женщин в этом наборе данных выше, чем среди взрослого населения США, потому что GSS не включает людей, находящихся в учреждениях, включая тюрьмы и армию, и эти группы населения с большей вероятностью будут мужчинами.
Упражнение: Разработчики Общего социального опроса решили представить пол как двоичную переменную. Какие альтернативы они могли бы рассмотреть? Каковы преимущества и недостатки их выбора?
Для получения дополнительной информации по этой теме вам может быть интересна эта статья: Уэстбрук и Саперштейн, Новых категорий недостаточно: переосмысление измерения пола в социальных опросах
Значения polviews
оцениваются по семибалльной шкале:
1 Extremely liberal (Чрезвычайно либеральный)
2 Liberal (Либерал)
3 Slightly liberal (Слегка либеральный)
4 Moderate (Умеренный)
5 Slightly conservative (Слегка консервативный)
6 Conservative (Консервативный)
7 Extremely conservative (Чрезвычайно консервативный)
Вот количество ответивших:
values(gss['polviews'])
counts | |
---|---|
values | |
1.0 | 1442 |
2.0 | 5808 |
3.0 | 6243 |
4.0 | 18943 |
5.0 | 7940 |
6.0 | 7319 |
7.0 | 1595 |
Я определю liberal
как True
для любого, чей ответ "чрезвычайно либеральный" ("Extremely liberal"), "либеральный" ("Liberal") или "слегка либеральный" ("Slightly liberal").
liberal = (gss['polviews'] < 4)
Вот количество значений True
и False
:
values(liberal)
counts | |
---|---|
values | |
False | 35797 |
True | 13493 |
И доля "либералов" ("liberal").
liberal.mean()
0.27374721038750255
Если мы выберем случайного человека в этом наборе данных, вероятность его либеральности составит около 27%.
Подводя итог тому, что мы сделали на данный момент:
Чтобы представить логическое утверждение вроде "этот респондент придерживается либеральных взглядов", мы используем логическую серию (Boolean series), которая содержит значения True
и False
.
Чтобы вычислить вероятность того, что утверждение истинно, мы используем функцию mean
, которая вычисляет долю значений True
в серии.
Чтобы сделать это вычисление более явным, я определю функцию, которая принимает логическую серию и возвращает вероятность:
def prob(A):
"""Computes the probability of a proposition, A.
A: Boolean series
returns: probability
"""
assert isinstance(A, pd.Series)
assert A.dtype == 'bool'
return A.mean()
Операторы assert
проверяют, является ли A
логической серией. В противном случае отображается сообщение об ошибке.
Использование этой функции для вычисления вероятностей делает код более читабельным.
Вот вероятности утверждений, которые мы уже вычислили.
prob(banker)
0.014769730168391155
prob(female)
0.5378575776019476
prob(liberal)
0.27374721038750255
Упражнение: значения partyid
кодируются следующим образом:
0 Strong democrat (Сильный демократ)
1 Not str democrat (Не строгий демократ)
2 Ind,near dem (Независимый, ближе к демократам)
3 Independent (Независимый)
4 Ind,near rep (Независимый, ближе к республиканцам)
5 Not str republican (Не строгий республиканец)
6 Strong republican (Сильный республиканец)
7 Other party (Другая партия)
Я определю democrat
, чтобы включить респондентов, которые выбрали "Strong democrat" или "Not str democrat":
democrat = (gss['partyid'] <= 1)
Используйте mean
, чтобы вычислить долю демократов в этом наборе данных.
Используйте prob
для вычисления той же доли (fraction), которую мы будем рассматривать как вероятность.
# Решение здесь
# Решение здесь
Теперь, когда у нас есть определение вероятности и функция, которая ее вычисляет, давайте перейдем к конъюнкции.
"Конъюнкция" - это еще одно название логической операции and
. Если у вас есть два утверждления, A
и B
, конъюнкция A and B
будет True
, если и A
и B
равны True
, и False
в противном случае.
Я продемонстрирую использование двух логических серий, созданных для перечисления каждой комбинации True
и False
:
A = pd.Series((True, True, False, False))
A
0 True 1 True 2 False 3 False dtype: bool
B = pd.Series((True, False, True, False))
B
0 True 1 False 2 True 3 False dtype: bool
Чтобы вычислить конъюнкцию A
и B
, мы можем использовать оператор &
, например:
A & B
0 True 1 False 2 False 3 False dtype: bool
Результатом является True
, только если A
и B
равны True
.
Чтобы более наглядно показать эту операцию, я помещу операнды и результат во фрейм данных:
table = pd.DataFrame()
table['A'] = A
table['B'] = B
table['A & B'] = A & B
table
A | B | A & B | |
---|---|---|---|
0 | True | True | True |
1 | True | False | False |
2 | False | True | False |
3 | False | False | False |
Такой способ представления логической операции называется таблицей истинности.
В предыдущем разделе мы вычислили вероятность того, что случайный респондент является банкиром:
prob(banker)
0.014769730168391155
И вероятность того, что респондент - демократ:
prob(democrat)
0.3662609048488537
Теперь мы можем вычислить вероятность того, что случайный респондент - банкир и демократ:
prob(banker & democrat)
0.004686548995739501
Как и следовало ожидать, prob(banker & democrat)
меньше, чем prob(banker)
, потому что не все банкиры - демократы.
Упражнение: Используйте prob
и оператор &
для вычисления следующих вероятностей.
Какова вероятность того, что случайный респондент окажется банкиром и либералом?
Какова вероятность того, что случайный респондент - женщина, банкир или либерал?
Какова вероятность того, что случайным респондентом окажется женщина, банкир и либеральный демократ?
Обратите внимание, что чем больше мы добавляем союзов, тем меньше вероятность.
# Решение здесь
# Решение здесь
# Решение здесь
Упражнение: Мы ожидаем, что конъюнкция будет коммутативной; то есть A & B
должно быть таким же, как B & A
.
Чтобы проверить, вычислите эти две вероятности:
prob(banker & liberal)
0.003306958815175492
prob(liberal & banker)
0.003306958815175492
Если они не совпадают, что-то пошло не так!
Условная вероятность - это вероятность, которая зависит от условия, но это может быть не самое полезное определение. Вот некоторые примеры:
Какова вероятность того, что респондент является демократом, учитывая его либеральность?
Какова вероятность того, что респондент - женщина, учитывая, что это банкир?
Какова вероятность того, что респондент является либералом, учитывая, что она женщина?
Начнем с первого пункта, который мы можем интерпретировать так: "Из всех респондентов, которые являются либералами, какая фракция - демократы?"
Мы можем вычислить эту вероятность в два этапа:
Выберите всех респондентов-либералов.
Вычислите долю выбранных респондентов-демократов.
Чтобы выбрать либеральных респондентов, мы можем использовать оператор квадратных скобок []
, например:
selected = democrat[liberal]
Результатом является логическая серия, содержащая подмножество значений в democrat
. В частности, он содержит только те значения, где liberal
равно True
.
Чтобы убедиться в этом, давайте проверим размерность результата:
len(selected)
13493
Если все пошло по плану, это должно быть таким же, как количество значений True
в liberal
:
liberal.sum()
13493
Хорошо.
selected
содержит значение democrat
для респондентов-либералов, поэтому среднее значение selected
- это доля либералов, которые являются демократами:
selected.mean()
0.5206403320240125
Чуть больше половины либералов - демократы. Если результат оказался ниже ожидаемого, имейте в виду:
Мы использовали несколько строгое определение понятия "Democrat", исключая независимых, которые "склоняются к демократии".
Набор данных включает респондентов еще с 1974 г .; в начале этого периода совпадение политических взглядов и партийной принадлежности было меньше, чем в настоящее время.
Давайте попробуем второй пример: "Какова вероятность того, что респондент - женщина, учитывая, что это банкир?"
Мы можем интерпретировать это следующим образом: "Какая доля из всех респондентов, которые являются банкирами, составляют женщины?"
Опять же, мы будем использовать оператор скобок, чтобы выбрать только банкиров:
selected = female[banker]
len(selected)
728
Как мы видели, в наборе данных 728 банкиров.
Теперь мы можем использовать mean
для вычисления условной вероятности того, что респондент - женщина, учитывая, что это банкир:
selected.mean()
0.7706043956043956
Около 77% банкиров в этом наборе данных - женщины.
Мы можем получить тот же результат, используя prob
:
prob(selected)
0.7706043956043956
Помните, что мы определили prob
, чтобы упростить чтение кода. Мы можем сделать то же самое с условной вероятностью.
Я определю функцию conditional
, чтобы взять две логических серии, A
и B
, и вычислить условную вероятность A
с учетом B
:
def conditional(A, B):
"""Conditional probability of A given B.
A: Boolean series
B: Boolean series
returns: probability
"""
return prob(A[B])
Теперь мы можем использовать conditional
для вычисления вероятности того, что либерал является демократом:
conditional(democrat, liberal)
0.5206403320240125
И вероятность того, что банкир - женщина:
conditional(female, banker)
0.7706043956043956
Результаты такие же, как выше.
Упражнение: Используйте conditional
, чтобы вычислить вероятность того, что респондент является либералом, учитывая, что он женщина.
Подсказка: ответ должен быть меньше 30%. Если ваш ответ составляет около 54%, вы допустили ошибку (см. Следующее упражнение).
# Решение здесь
Упражнение: В предыдущем упражнении мы видели, что конъюнкция коммутативна; то есть prob(A & B)
всегда равно prob(B & A)
.
Но условная вероятность НЕ коммутативна; то есть conditional(A, B)
не то же самое, что conditional(B, A)
.
Это должно быть ясно, если посмотрим на пример. Ранее мы вычисляли вероятность того, что респондент - женщина, учитывая, что это банкир.
conditional(female, banker)
0.7706043956043956
Результат показывает, что большинство банкиров - женщины. Это не то же самое, что вероятность того, что респондент - банкир, учитывая, что она женщина:
conditional(banker, female)
0.02116102749801969
Лишь около 2% респондентов-женщин - банкиры.
Упражнение: Используйте conditional
для вычисления следующих вероятностей:
Какова вероятность того, что респондент является либералом, учитывая, что он демократ?
Какова вероятность того, что респондент является демократом, учитывая его либеральность?
Тщательно продумайте порядок серий, которые вы передадите в conditional
.
conditional(liberal, democrat)
0.3891320002215698
conditional(democrat, liberal)
0.5206403320240125
Мы можем комбинировать условную вероятность и конъюнкцию. Например, вот вероятность того, что респондент - женщина, учитывая, что это либеральный демократ.
conditional(female, liberal & democrat)
0.576085409252669
Почти 57% либерал-демократов - женщины.
И вот вероятность того, что они либеральные женщины, учитывая, что это банкир:
conditional(liberal & female, banker)
0.17307692307692307
Около 17% банкиров - либеральные женщины.
Упражнение: Какая часть женщин-банкиров принадлежит к либеральным демократам?
Подсказка: если ваш ответ меньше 1%, значит, вы получили его наоборот. Помните, что условная вероятность не коммутативна.
# Решение здесь
На этом этапе вы должны понять определение вероятности, по крайней мере, в простом случае, когда у нас есть конечный набор данных. Позже мы рассмотрим случаи, когда определение вероятности более спорно.
И вы должны понимать конъюнкцию и условную вероятность. В следующих блокнотах мы исследуем взаимосвязь между конъюнкцией и условной вероятностью и используем ее для получения Теорема Байеса, лежащая в основе байесовской статистики.